/* Turska Framework/UI library (Turs2)
 * Copyright 2003-2009 Jetro Lauha
 * All rights reserved.
 * Web: http://iki.fi/jetro/turska/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of EITHER:
 *   (1) The GNU Lesser General Public License as published by the Free
 *       Software Foundation; either version 2.1 of the License, or (at
 *       your option) any later version. The text of the GNU Lesser
 *       General Public License is included with this library in the
 *       file LICENSE-LGPL.txt.
 *   (2) The BSD-style license that is included with this library in
 *       the file LICENSE-BSD.txt.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
 * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details.
 *
 * $Id: T2IMGUI.h 131 2009-06-05 05:58:05Z jlauha $
 * $Revision: 131 $
 */

#ifndef T2IMGUI_H_INCL
#define T2IMGUI_H_INCL


namespace turska
{
    enum IMGUI_AUTO_ID
    {
        IMGUI_AI_COUNTER      = -1
    };
    
    enum IMGUI_ACTIVE_WIDGET_STATUS
    {
        IMGUI_AWS_NONE        = -1,
        IMGUI_AWS_UNAVAILABLE = -2
    };

    //! Default widget states.
    enum IMGUI_WIDGET_STATE
    {
        IMGUI_WS_DEFAULT     = 0x0,
        IMGUI_WS_HOT         = 0x1,
        IMGUI_WS_ACTIVE      = 0x2,
        IMGUI_WS_HOT_ACTIVE  = 0x3,
        IMGUI_WS_COUNT, // count of states

        //! Bitmask for checking if state is one of "hot" states.
        IMGUI_WS_MASK_HOT    = 0x1,
        //! Bitmask for checking if state is one of "active" states.
        IMGUI_WS_MASK_ACTIVE = 0x2
    };

    //! Widget orientation (used e.g. by slider).
    enum IMGUI_WIDGET_ORIENTATION
    {
        IMGUI_WO_HORIZONTAL = 0,
        IMGUI_WO_VERTICAL
    };

    class IMGUIWidgetStyle
    {
    public:
        virtual ~IMGUIWidgetStyle() {}
        virtual bool isKeyFocusAllowed() { return true; }
    };

    class IMGUIButtonStyle;
    class IMGUISliderStyle;
    class IMGUITextFieldStyle;

    //! Immediate-mode graphical user interface (IMGUI).
    class IMGUI
    {
    public:

        IMGUI();
        virtual ~IMGUI();

        virtual void begin(UI32 time, I16 groupId = 0, bool renderingEnabled = true);
        virtual void end();

        //! Resets hot/active component id states.
        virtual void resetState();

        // If width or height is 0, it's assumed that the style object knows better.
        // x,y refers to top-left corner

        virtual bool button(REAL x, REAL y, I32 id = IMGUI_AI_COUNTER,
                            IMGUIButtonStyle *buttonStyle = 0,
                            REAL width = 0, REAL height = 0,
                            const C8 *text = 0, Image *image = 0);

        // checkbox draws its text and image when its value is true
        virtual bool checkBox(REAL x, REAL y, bool &value, I32 id = IMGUI_AI_COUNTER,
                              IMGUIButtonStyle *buttonStyle = 0,
                              REAL width = 0, REAL height = 0,
                              const C8 *text = 0, Image *image = 0);

        virtual void slider(REAL x, REAL y, I32 &value, I32 id = IMGUI_AI_COUNTER,
                            IMGUI_WIDGET_ORIENTATION axis = IMGUI_WO_HORIZONTAL,
                            IMGUISliderStyle *sliderStyle = 0,
                            I32 minValue = 0, I32 maxValue = 100, I32 step = 10,
                            REAL width = 0, REAL height = 0);
        virtual void slider(REAL x, REAL y, REAL &value, I32 id = IMGUI_AI_COUNTER,
                            IMGUI_WIDGET_ORIENTATION axis = IMGUI_WO_HORIZONTAL,
                            IMGUISliderStyle *sliderStyle = 0,
                            REAL minValue = 0, REAL maxValue = 1, REAL step = (REAL)0.1f,
                            REAL width = 0, REAL height = 0);

        virtual void textField(REAL x, REAL y, C8 *string, I32 maxStringLength, I32 id = IMGUI_AI_COUNTER,
                               IMGUITextFieldStyle *textFieldStyle = 0, REAL width = 0, REAL height = 0);

        /** Defines a "drag'n'drop" target using a given button style, or if it's 0,
         *  given width and height.
         * Returns true if another widget is "dropped" in this target. Id of the
         * source widget is written to dragId.
         */
        virtual bool drop(REAL x, REAL y, I32 &dragId, IMGUIButtonStyle *buttonStyle = 0,
                          REAL width = 0, REAL height = 0, const C8 *text = 0, Image *image = 0);

        virtual void onKeyDown(const KeyEvent &key);
        virtual void onMouseDown();
        virtual void onMouseUp();
        virtual void onMouseMotion(I32 x, I32 y);

        void setAutoIdCounter(I32 value) { mAutoIdCounter = value; }
        I32 getAutoIdCounter() const { return mAutoIdCounter; }
        I32 getMouseX() const { return mMouseX; }
        I32 getMouseY() const { return mMouseY; }
        bool isMouseDown() const { return mMouseDown; }
        // Returns widget id or one of IMGUI_ACTIVE_WIDGET_STATUS.
        I32 getHotMouseWidgetId() const { return mHotMouseWidgetId; }
        // Returns widget id or one of IMGUI_ACTIVE_WIDGET_STATUS.
        I32 getActiveMouseWidgetId() const { return mActiveMouseWidgetId; }
        void setActiveMouseWidgetId(I32 id) { mActiveMouseWidgetId = id; }
        // Returns widget id or one of IMGUI_ACTIVE_WIDGET_STATUS.
        I32 getActiveKeyWidgetId() const { return mActiveKeyWidgetId; }
        void setActiveKeyWidgetId(I32 id) { mActiveKeyWidgetId = id; }
        // Returns true if rendering is enabled, or false if rendering is disabled.
        bool isRenderingEnabled() const { return mRenderingEnabled; }
        // Returns the last rendered rectangle.
        const Rectangle & getLastRenderedRectangle() const { return mLastRenderedRectangle; }
        // Returns the currently active widget id or one of IMGUI_ACTIVE_WIDGET_STATUS.
        I32 getCurrentWidgetId() const { return mCurrentWidgetId; }
        // Returns current time recorded by begin().
        UI32 getTime() const { return mTime; }
        // Returns last key event time (timestamp taken from getTime).
        UI32 getLastKeyEventTime() const { return mLastKeyEventTime; }

    protected:

        I32 defaultWidgetStateLogic(I32 id, bool hotNow, IMGUIWidgetStyle *style);
        I32 buttonLogic(I32 id, IMGUIButtonStyle *buttonStyle,
                        REAL x, REAL y, REAL width, REAL height,
                        const C8 *text, Image *image);
        bool isButtonClicked(I32 id, IMGUIButtonStyle *style);

        I32 mAutoIdCounter;
        I32 mMouseX;
        I32 mMouseY;
        bool mMouseDown;
        I32 mPreviousWidgetId;
        I32 mHotMouseWidgetId, mOldHotMouseWidgetId;
        I32 mActiveMouseWidgetId, mOldActiveMouseWidgetId;
        I32 mActiveKeyWidgetId;
        I32 mPreviousKeyWidgetId;
        bool mRenderingEnabled;
        Rectangle mLastRenderedRectangle;
        I32 mCurrentWidgetId;
        UI32 mTime;
        UI32 mLastKeyEventTime;
        
        KeyEvent mKeyEvent; //!< Note: platformEvent member of mKeyEvent is always 0.
    };

} // namespace turska


#endif // !T2IMGUI_H_INCL
